using System;
using SexpSharp.Serialization;

namespace SexpSharp.Serialization.Tests
{
	[Serializable]
	public class Sample1
	{
		public bool b = true;
		public short s = 42;
		public int i = -1002;
		public long l = -32000;
		public string str = "I am the very model of a modern major general";
		public decimal d = 3.14159m;

        public override bool Equals(object o)
        {
            Sample1 that = (Sample1) o;
            return (that.b == b
                    && that.s == s
                    && that.i == i
                    && that.l == l
                    && that.str == str
                    && that.d == d);
        }

        public override string ToString()
        {
            return b + " " + s + " " + i + " " + l + " " + str + " " + d;
        }
	}

	[Serializable]
	public struct Sample2
	{
		public bool b;
		public short s;
		public int i;
		public long l;
		public string str;
		public decimal d;

		public object InitMe()
		{
			b = true;
			s = 42;
			i = -1002;
			l = -32000;
			str = "I am the very model of a modern major general";
			d = 3.14159m;
			return this;
		}

        public bool Equals(object o)
        {
            Sample2 that = (Sample2) o;
            return (that.b == b
                    && that.s == s
                    && that.i == i
                    && that.l == l
                    && that.str == str
                    && that.d == d);
        }
	}

	[Serializable,SexpFixed]
	public struct Fixed1
	{
		public bool b;
		public short s;
		public int i;
		public long l;
		public string str;
		public decimal d;

		public object InitMe()
		{
			b = true;
			s = 42;
			i = -1002;
			l = -32000;
			str = "I am the very model of a modern major general";
			d = 3.14159m;
			return this;
		}

        public bool Equals(object o)
        {
            Fixed1 that = (Fixed1) o;
            return (that.b == b
                    && that.s == s
                    && that.i == i
                    && that.l == l
                    && that.str == str
                    && that.d == d);
        }
	}

	[Serializable, SexpTypeName("sample-type-name")]
	public class Sample3
	{
		[SexpFieldName("some-bool")]
		public bool b = true;
		[SexpFieldName("some-short")]
		public short s = 42;
		[SexpFieldName("some-int")]
		public int i = -1002;
		[SexpFieldName("some-long")]
		public long l = -32000;
		[SexpFieldName("some-string")]
		public string str = "I am the very model of a modern major general";
		[SexpFieldName("some-decimal")]
		public decimal d = 3.14159m;

        public override bool Equals(object o)
        {
            Sample3 that = (Sample3) o;
            return (that.b == b
                    && that.s == s
                    && that.i == i
                    && that.l == l
                    && that.str == str
                    && that.d == d);
        }

        public override string ToString()
        {
            return b + " " + s + " " + i + " " + l + " " + str + " " + d;
        }
	}

	[Serializable, SexpFixed, SexpTypeName("new-type-name")]
	public struct Fixed2
	{
		public bool b;
		public short s;
		public int i;
		public long l;
		public string str;
		public decimal d;

		public object InitMe()
		{
			b = true;
			s = 42;
			i = -1002;
			l = -32000;
			str = "I am the very model of a modern major general";
			d = 3.14159m;
			return this;
		}

        public bool Equals(object o)
        {
            Fixed2 that = (Fixed2) o;
            return (that.b == b
                    && that.s == s
                    && that.i == i
                    && that.l == l
                    && that.str == str
                    && that.d == d);
        }
	}

    [Serializable]
    public enum TestEnum
    {
        ValueOne,
        ValueTwo,
        ValueThree
    }

    [Serializable, SexpTypeName("test-enum")]
    public enum TestEnum2
    {
        ValueOne,
        ValueTwo,
        ValueThree
    }

    [Serializable]
    public class Cycle1
    {
        public Cycle2 cycle;
        public int foo;

        public override bool Equals(object o)
        {
            if (o is Cycle1)
            {
                return foo == ((Cycle1) o).foo;
            }
            return false;
        }
    }

    [Serializable]
    public class Cycle2
    {
        public Cycle1 cycle;
        public int foo;        

        public override bool Equals(object o)
        {
            if (o is Cycle2)
            {
                return foo == ((Cycle2) o).foo;
            }
            return false;
        }
    }
}